<!-- The documentation for the l-system renderer. -->

<HTML><HEAD>
<TITLE>L-System Renderer</TITLE>
</HEAD><BODY>

<H1>L-System Renderer</H1>

<P ALIGN="center"><IMG SRC="images/lsys-render-2d.png" ALT="Rendering of the Dragon Fractal" WIDTH="413" HEIGHT="428" ALIGN="middle" BORDER="1"></P>

<P>The L-system renderer available in the input menu allows one to take an L-system and render that system for various levels of substitution.  In the example picture we see the rendering of the dragon L-system given <A HREF="gui.lsystem.LSystemInputPane.html">here</A>.</P>

<P>JFLAPs L-system renderer subscribes to the canonical "turtle" metaphor, that is, an imaginary entity that moves about in a world, turning this way and that, and marking its territory as it moves forward.  Functionally it is similar to other L-system renderers that exist, but it has a few major differences from the majority I encountered:</P>

<UL>
<LI>It can render 3D L-systems (albeit as orthogonal projections).</LI>
<LI>Assignable values and parameters may take the form of mathematical expressions.</LI>
<LI>It has an actual GUI slightly more complex than a handful of buttons and a drawing area.  I don't know why this is unusual, but it is.</LI>
</UL>

<H2>Definition of an L-System</H2>

<H3>Parameters</H3>

<P>During the definition of the L-system the user has the chance to define some parameters in the table of the L-system input pane to affect the initial state of the drawing environment.  What follows are a list of all recognized parameters, their default value for the renderer if they are not defined, and how they are used.</P>

<TABLE WIDTH="100%" CELLPADDING="5" ALIGN="center">
<TR VALIGN="top"><TH>Parameter</TH> <TH>Default</TH> <TH>Description</TH></TR>

<TR VALIGN="top"><TD>distance</TD> <TD>15</TD>
<TD>Lines are drawn with length <VAR>distance</VAR>.</TD></TR>

<TR VALIGN="top"><TD>color</TD> <TD>black</TD>
<TD>Lines are drawn with the color specified by <VAR>color</VAR>.  Colors may be specified by name.  The acceptable color names are
<VAR>black</VAR>,
<VAR><FONT COLOR="#0000FF">blue</FONT></VAR>,
<VAR><FONT COLOR="#810000">brown</FONT></VAR>,
<VAR><FONT COLOR="#00CCCC">cyan</FONT></VAR>,
<VAR><FONT COLOR="#333333">darkGray</FONT></VAR>,
<VAR><FONT COLOR="#6D6F00">darkOliveGreen</FONT></VAR>,
<VAR><FONT COLOR="#0A7F00">darkOliveGreen2</FONT></VAR>,
<VAR><FONT COLOR="#00009C">dukeBlue</FONT></VAR>,
<VAR><FONT COLOR="#007F00">forestGreen</FONT></VAR>,
<VAR><FONT COLOR="#FFD600">goldenrod</FONT></VAR>,
<VAR><FONT COLOR="#666666">gray</FONT></VAR>,
<VAR><FONT COLOR="#00CC00">green</FONT></VAR>,
<VAR><FONT COLOR="#999999">lightGray</FONT></VAR>,
<VAR><FONT COLOR="#FF00FF">magenta</FONT></VAR>,
<VAR><FONT COLOR="#BE0000">maroon</FONT></VAR>,
<VAR><FONT COLOR="#725D00">oliveDrab</FONT></VAR>,
<VAR><FONT COLOR="#FF9900">orange</FONT></VAR>,
<VAR><FONT COLOR="#FC7600">orangeRed</FONT></VAR>,
<VAR><FONT COLOR="#EE99EE">pink</FONT></VAR>,
<VAR><FONT COLOR="#D100FF">purple</FONT></VAR>,
<VAR><FONT COLOR="#FF0000">red</FONT></VAR>,
<VAR><FONT COLOR="#87B26E">springGreen</FONT></VAR>,
<VAR><FONT COLOR="#D200CD">violetRed</FONT></VAR>,
<VAR>white</VAR>, and
<VAR><FONT COLOR="#CCCC00">yellow</FONT></VAR>.  Color names are case sensitive!<P>Additionally, one may specify a given color according to three numbers of the form <VAR>a,b,c</VAR>.  If <VAR>a</VAR>, <VAR>b</VAR>, and <VAR>c</VAR> are <STRONG>all</STRONG> within the range of [0.0, 1.0], they are interpreted as hue, saturation, and brightness values respectively (where the hue range of 0 through 1 represents a full tour around the color wheel), and are used to define a color appropriately.  If any of those values is outside of that range they are treated as standard red, green, blue respectively, with each channel value ranging in increasing intensity from 0 to 255 as is normal.  For example, <FONT COLOR="#0000FF">blue</FONT> may be defined either as an HSB color by <VAR>.667,1,1</VAR> or as an RGB color by <VAR>0,0,255</VAR>.</TD></TR>

<TR VALIGN="top"><TD>polygonColor</TD> <TD><FONT COLOR="#FF0000">red</FONT></TD>
<TD>Polygons are filled with the color specified by <VAR>polygonColor</VAR>.  This parameter accepts the same value types as the <VAR>color</VAR> parameter.</TD></TR>

<TR VALIGN="top"><TD>angle</TD> <TD>15</TD>
<TD>Whenever the turtle is turned, pitched, or rolled, it does with <VAR>angle</VAR> degrees.  Note that this parameter may also be named by <VAR>angleIncrement</VAR> (a compatibility measure with my first implementation).</TD></TR>

<TR VALIGN="top"><TD>hueChange</TD> <TD>10</TD>
<TD>When the command to increment the hue of the current drawing color is given the degrees the hue is turned is <VAR>hueChange</VAR>.</TD></TR>

<TR VALIGN="top"><TD>lineWidth</TD> <TD>1.0</TD>
<TD>Lines are drawn with a pixel-width of <VAR>lineWidth</VAR>.  This parameter accepts real number values greater or equal to zero (e.g., 4, 1.5, 0).</TD></TR>

<TR VALIGN="top"><TD>lineIncrement</TD> <TD>1.0</TD>
<TD>When the line width (the parameter <VAR>lineWidth</VAR>) is incremented or decremented, it is incremented or decremented by this amount.</TD></TR>
</TABLE>

<H3>Drawing & Turtle Symbols</H3>

<P>The following symbols are used to move the turtle about, and otherwise affect the state of the drawing.  Whenever appropriate, a <VAR>parameter</VAR> will appear to indicate that the action associated with the symbol uses a quantity that can be changed.  For example, <VAR>&</VAR> causes the turtle to pitch down by <VAR>angle</VAR> degrees.  If the user has specified that <VAR>angle=30</VAR>, then the turtle will pitch down by 30 degrees.</P>

<TABLE WIDTH="100%" CELLPADDING="5" ALIGN="center">
<TR VALIGN="top"><TH>Symbol</TH> <TH>Description</TH> </TR>
<TR VALIGN="top"><TD>g</TD>
<TD>Move forward <VAR>distance</VAR> in the <VAR>y</VAR> direction with the pen down, producing a line of width <VAR>lineWidth</VAR> and of color <VAR>color</VAR>, <STRONG>unless</STRONG> we are building a polygon, in which case a line is not drawn and the end point of this move is added to the polygon.</TD></TR>

<TR VALIGN="top"><TD>g(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified distance.</TD></TR>

<TR VALIGN="top"><TD>f</TD>
<TD>Move forward <VAR>distance</VAR> in the <VAR>y</VAR> direction with the pen up, producing no line but changing the position of the turtle.</TD></TR>

<TR VALIGN="top"><TD>f(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified distance.</TD></TR>

<TR VALIGN="top"><TD>+</TD>
<TD>Turn right (clockwise in 2D) by <VAR>angle</VAR> degrees.  Turns about the <VAR>z</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>+(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>-</TD>
<TD>Turn left (counter-clockwise in 2D) by <VAR>angle</VAR> degrees.  Turns about the <VAR>z</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>-(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>&</TD>
<TD>Pitch down by <VAR>angle</VAR> degrees.  Turns about the <VAR>x</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>&(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>^</TD>
<TD>Pitch up by <VAR>angle</VAR> degrees.  Turns about the <VAR>x</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>^(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>/</TD>
<TD>Roll right by <VAR>angle</VAR> degrees.  Turns about the <VAR>y</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>/(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>*</TD>
<TD>Roll left by <VAR>angle</VAR> degrees.  Turns about the <VAR>y</VAR>-axis.</TD></TR>

<TR VALIGN="top"><TD>*(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>[</TD>
<TD>Begin branch (i.e. push turtle state on stack).</TD>
</TR>

<TR VALIGN="top"><TD>]</TD>
<TD>End branch (i.e. pop turtle state from stack).  If there is no corresponding <VAR>[</VAR>, this has no effect.  Aside from restoring position and direction, any changes to variables since the last <VAR>[</VAR> will be undone.</TD></TR>

<TR VALIGN="top"><TD>!</TD>
<TD>Increment <VAR>lineWidth</VAR> by <VAR>lineIncrement</VAR>.</TD></TR>

<TR VALIGN="top"><TD>!(<VAR>value</VAR>)</TD>
<TD>Like the above, but increments by the specified amount.</TD></TR>

<TR VALIGN="top"><TD>~</TD>
<TD>Decrement <VAR>lineWidth</VAR> by <VAR>lineIncrement</VAR>, with a minimum <VAR>lineWidth</VAR> of zero attainable.</TD></TR>

<TR VALIGN="top"><TD>~(<VAR>value</VAR>)</TD>
<TD>Like the above, but decrements by the specified amount.</TD></TR>

<TR VALIGN="top"><TD>{</TD>
<TD>Begin the definition of a polygon.  The turtle position when the <VAR>{</VAR> is processed will be the first point in the polygon, and the end point reached by each <VAR>g</VAR> directive until the close of the polygon will be added to the polygon.</TD></TR>

<TR VALIGN="top"><TD>}</TD>
<TD>Ends the definition of a polygon.  The turtle position when the <VAR>}</VAR> is processed will not be added to the polygon.  The polygon will be filled with the color <VAR>polygonColor</VAR> and will have no outline.</TD></TR>

<TR VALIGN="top"><TD>%</TD>
<TD>Turn by 180 degrees about the <VAR>z</VAR>-axis, the same axis as the <VAR>+</VAR> and <VAR>-</VAR> turns.</TD></TR>

<TR VALIGN="top"><TD>#</TD>
<TD>Increments the hue angle of <VAR>color</VAR> by <VAR>hueChange</VAR>.  Changing the hue angle will have no effect if <VAR>color</VAR> has no saturation, i.e., if <VAR>color</VAR> is black, grey, or white.</TD></TR>

<TR VALIGN="top"><TD>#(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>@</TD>
<TD>Decrements the hue angle of <VAR>color</VAR> by <VAR>hueChange</VAR>.</TD></TR>

<TR VALIGN="top"><TD>@(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>##</TD>
<TD>Increments the hue angle of <VAR>polygonColor</VAR> by <VAR>hueChange</VAR>.  Changing the hue angle will have no effect if <VAR>polygonColor</VAR> has no saturation, i.e., if <VAR>polygonColor</VAR> is black, grey, or white.</TD></TR>

<TR VALIGN="top"><TD>##(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD>@@</TD>
<TD>Decrements the hue angle of <VAR>polygonColor</VAR> by <VAR>hueChange</VAR>.</TD></TR>

<TR VALIGN="top"><TD>@@(<VAR>value</VAR>)</TD>
<TD>Like the above, but with a specified number of degrees.</TD></TR>

<TR VALIGN="top"><TD><VAR>parameter</VAR>=<VAR>value</VAR></TD>
<TD>This will attempt to set a parameter named <VAR>parameter</VAR> to <VAR>value</VAR>.  For example, the symbol <VAR>angle=20</VAR> will cause all subsequent turns to be made with 20 degrees, <VAR>color=red</VAR> will cause all subsequent <VAR>g</VAR> directives to produce red lines, and soforth.  The names of parameters and acceptable values is the same as for the mappings in the parameter table.  There must be no whitespace in the <VAR>parameter=value</VAR> symbol, or else it shall not be processed as a single symbol.</TD></TR>
</TABLE>

<H3>Values</H3>

<P>You may have noticed that in the list of symbols were a number of symbols that take an argument, for example, the turn right symbol + can appear in the form +(<VAR>value</VAR>) to turn a specified number of degrees, and you can also say lineIncrement=<VAR>value</VAR> to set the amount the line width changes when the renderer encounters the symbols like ! and ~.</P>

<P>Every <VAR>value</VAR> may be as simple as a number, but it may be a mathematical expression involving parameters as values.  One could say <VAR>distance=distance+2</VAR>, which will increment subsequent line lengths by 2.  Moreover, if in the parameters list one specified that <VAR>foo</VAR> was 100, then the symbol <VAR>g(3+(8+foo)/2)</VAR> would yield a line of length 57.  All <VAR>g</VAR> symbols are functionally equivalent to <VAR>g(distance)</VAR>.</P>

<P>The operators allowed in a value are + (addition), - (subtraction), * (multiplication), / (division), ^ (power), ( and ) (parentheses), and they obey the usual rules of order of operations and soforth.  If an undefined symbol appears in a mathematical expression, then a value of 0 is assumed for that symbol.</P>

<P>For higher performance, avoid the frequent use of expressions.  For example, if you're curious about the relative performance of <VAR>+(5*angle)</VAR> versus <VAR>+ + + + +</VAR>, the <VAR>+ + + + +</VAR> will tend to be faster, though your milage may vary for your particular JVM.</P>

<H2>Interface</H2>

<P>The L-system renderer interface has 5 distinct components of interest.</P>

<P ALIGN="center"><IMG SRC="images/hilbert3d.png" ALT="3D Hilbert rendering with annotations" WIDTH="432" HEIGHT="539" BORDER="1" ALIGN="middle"></P>

<OL TYPE="1">
<LI>While the system is busy rendering an L-system, the progress back will report the amount done to the user.</LI>
<LI>This field will display the current symbols being drawn up to a point; since most interesting L-systems are exponential in their growth, this will usually be omitted since longer strings of symbols are usually quite nonsensicle to the user.</LI>
<LI>This spinner allows the user to specify the depth of L-system substitution recursion.  A level of 0 means that only the axiom will be rendered.</LI>
<LI>The major portion of the view is used to display the rendering of the L-system.  If the rendering extends beyond the extent of the view, scrollbars will appear to allow the user to inspect all of the rendering.</LI>
<LI>Though of little use for 2D rendering, for L-systems that take advantage of 3D renderings the ability to look at the rendering from different angles is important.  By twiddling these values the user can get a feel for the shape of the rendering.</LI>
</OL>

<H2>Notes</H2>

The 3D "renderer," as it is, is nothing more than the standard Java 2D graphics where the <VAR>z</VAR> coordinate is ignored for drawing.  Consequences of this are that all projections are orthogonal and that lines drawn over each other may not be in sensible depth order.  Until either <CODE>gl4java</CODE> or (heaven forbid) <CODE>Java3D</CODE> becomes standard issue for the JVM on all reasonable platforms, this system shall persist.

</BODY></HTML>
